package com.scalar.chiptrack.operations.processtypesetup.actions;

import java.util.ArrayList;
import java.util.HashMap;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.util.LabelValueBean;

import com.scalar.ScalarException;
import com.scalar.chiptrack.ChipTrackAction;
import com.scalar.chiptrack.users.User;
import com.scalar.chiptrack.users.Functionality;
import com.scalar.chiptrack.utils.Logger;
import com.scalar.chiptrack.finance.openpo.dao.PurchaseOrderDAO;
import com.scalar.chiptrack.commons.SessionKeys;
import com.scalar.chiptrack.commons.UOM;
import com.scalar.chiptrack.operations.processtypesetup.ProcessParameters;
import com.scalar.chiptrack.operations.processtypesetup.dao.ProcessTypeSetupDAO;
import com.scalar.chiptrack.operations.processtypesetup.forms.ProcessTypeSetupForm;

public class ProcessTypeSetupAction extends ChipTrackAction
{
	public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception 
	{
		ProcessTypeSetupForm processTypeSetupForm	= (ProcessTypeSetupForm) form;
		HashMap<String,String> errors				= new HashMap<String,String>();
		HashMap<String,String> info 				= new HashMap<String,String>();
		HttpSession session							= request.getSession();
		String action 								= processTypeSetupForm.getAction();
		String retVal								= "failure";
		ArrayList processList                       = null;
		ArrayList units                             = null;
        User user = ( User ) session.getAttribute ( SessionKeys.USER_KEY );
		processList = ( ArrayList )session.getAttribute( "processList" );
		units       = ( ArrayList )session.getAttribute( "units" );
        String noModifyRightsFlagName = "showModifyNotAllowedMessage";
        String noDeleteRightsFlagName = "showDeleteNotAllowedMessage";

        if ( user != null && user.isActionAllowed ( Functionality.PROCESS_TYPE_SETUP, User.USER_ACTION_MODIFY ) )
        {
            request.setAttribute ( noModifyRightsFlagName , Boolean.toString( false ) );
        }
        else
        {
            request.setAttribute ( noModifyRightsFlagName , Boolean.toString( true ) );
        }

		if( action.equalsIgnoreCase( "new" ) )
		{
			ArrayList parameters = new ArrayList();
			processTypeSetupForm.setProcessName( "" );
			processTypeSetupForm.setProcessType( "" );
			processTypeSetupForm.setProcessTypeId( -1 );
            processTypeSetupForm.setProcessOrder("");
            processTypeSetupForm.setProcessParameters( parameters );
			if( ( processList == null ) || ( units == null ) )
			{
				session.setAttribute( "processList", getParentProcessNames() );
				session.setAttribute( "units", ProcessTypeSetupDAO.getUnitsOfMesurment() );
			}
			retVal = "success";
		}
		else if( action.equalsIgnoreCase( "parameters" ) )
		{
			ArrayList parameterList = fetchSystemParameters( processTypeSetupForm );
			processTypeSetupForm.setProcessParameters( parameterList );
            String processType 	 = processTypeSetupForm.getProcessType() ;
            if( !( "".equalsIgnoreCase( processType ) ) || processType == null )
            {
                parameterList.add( new ProcessParameters() );
                request.setAttribute( "showSystemParameters", "true" );
                request.setAttribute( "showUserParameters", "true" );
            }
            HashMap comboMap = ProcessTypeSetupDAO.getComboMapForProcessType( null, processTypeSetupForm.getProcessType() );
            checkParameterValuesInComboMap ( processTypeSetupForm.getProcessParameters(), comboMap );
            request.setAttribute ( "comboMap",  comboMap );
            /*if ( processType != null && processType.equalsIgnoreCase( ProcessTypes.assembly ))
            {
                request.setAttribute( "packageTypeList", PurchaseOrderDAO.loadPackageTypeList() );
            }*/
			retVal = "success";
		}
		else if( action.equalsIgnoreCase( "addMore" ) )
		{
			if( ( processList == null ) || ( units == null ) )
			{
				session.setAttribute( "processList", getParentProcessNames() );
				session.setAttribute( "units", ProcessTypeSetupDAO.getUnitsOfMesurment() );
			}
			processTypeSetupForm.getProcessParameters().add( new ProcessParameters() );
			request.setAttribute( "showSystemParameters", "true" );
			request.setAttribute( "showUserParameters", "true" );

            HashMap comboMap = ProcessTypeSetupDAO.getComboMapForProcessType( null, processTypeSetupForm.getProcessType() );
            checkParameterValuesInComboMap ( processTypeSetupForm.getProcessParameters(), comboMap );
            request.setAttribute ( "comboMap",  comboMap );
            /*if ( processTypeSetupForm.getProcessType() != null && processTypeSetupForm.getProcessType().equalsIgnoreCase( ProcessTypes.assembly ))
            {
                request.setAttribute( "packageTypeList", PurchaseOrderDAO.loadPackageTypeList() );
            }*/

			retVal = "success";
		}
		else if( action.equalsIgnoreCase("save") )
		{
			try
			{
				if( ProcessTypeSetupDAO.isProcessExists( processTypeSetupForm.getProcessName() ) )
				{
                    errors.put( processTypeSetupForm.getProcessName(), " process already exists please select another process name");
					request.setAttribute( "showSystemParameters", "true" );
					request.setAttribute( "showUserParameters", "true" );
                    HashMap comboMap = ProcessTypeSetupDAO.getComboMapForProcessType( null, processTypeSetupForm.getProcessType() );
                    checkParameterValuesInComboMap ( processTypeSetupForm.getProcessParameters(), comboMap );
                    request.setAttribute ( "comboMap",  comboMap );
                    /*if ( processTypeSetupForm.getProcessType() != null && processTypeSetupForm.getProcessType().equalsIgnoreCase( ProcessTypes.assembly ))
                    {
                        request.setAttribute( "packageTypeList", PurchaseOrderDAO.loadPackageTypeList() );
                    }*/
					retVal = "success";
				}
				else
				{
                    if ( ProcessTypeSetupDAO.isProcessOrderExists( processTypeSetupForm.getProcessOrder() ))
                    {
                        errors.put( processTypeSetupForm.getProcessOrder(), " process OrderNo already exists please enter another process No");
                        request.setAttribute( "showSystemParameters", "true" );
                        request.setAttribute( "showUserParameters", "true" );
                        HashMap comboMap = ProcessTypeSetupDAO.getComboMapForProcessType( null, processTypeSetupForm.getProcessType() );
                        checkParameterValuesInComboMap ( processTypeSetupForm.getProcessParameters(), comboMap );
                        request.setAttribute ( "comboMap",  comboMap );

                        retVal = "success";
                    }
                    else
                    {
                        ProcessTypeSetupDAO.saveProcessDetails( processTypeSetupForm );
					    info.put( processTypeSetupForm.getProcessName(), "saved succesfully" );

					    retVal = "search";
                    }
                }
			}
			catch ( ScalarException e )
			{
				errors.put( processTypeSetupForm.getProcessName(), "Could not be saved " );
				retVal = "search";
			}

		}
		else if( action.equalsIgnoreCase( "modify" ) || action.equalsIgnoreCase( "view" ) || action.equalsIgnoreCase( "delete" ) )
		{
			try
			{
				ProcessTypeSetupDAO.loadProcess( processTypeSetupForm );

				if( action.equalsIgnoreCase( "delete" ) )
				{
                    if ( user != null && user.isActionAllowed ( Functionality.PROCESS_TYPE_SETUP, User.USER_ACTION_DELETE ) )
                    {
                        request.setAttribute ( noDeleteRightsFlagName , Boolean.toString( false ) );
                    }
                    else
                    {
                        request.setAttribute ( noDeleteRightsFlagName , Boolean.toString( true ) );
                    }
                    request.setAttribute( noModifyRightsFlagName, Boolean.toString( false ) );
					request.setAttribute( "confirm" , "true" );
					processTypeSetupForm.setAction( "view" );
				}
                if( action.equalsIgnoreCase( "view" ) )
                {
                    request.setAttribute( noDeleteRightsFlagName, Boolean.toString( false ) );
                    request.setAttribute( noModifyRightsFlagName, Boolean.toString( false ) );
                }

				request.setAttribute( "showSystemParameters", "true" );

				ArrayList parameterList = processTypeSetupForm.getProcessParameters();
				ArrayList systemParameterList 	= null;
				ProcessParameters parameter 	= null;
				ProcessParameters sysParameter 	= null;
				boolean parameterPresent 		= false;

				boolean showUserParameters = false;

				for( int i = 0; i < parameterList.size(); i++ )
				{
					parameter = (ProcessParameters)parameterList.get( i );
					if( parameter.getSysParam() == false )
					{
						showUserParameters = true;
						break;
					}
				}

				// If the System Parameter is not available in the Parameter List add that
				if( action.equalsIgnoreCase( "modify" ) )
				{
					systemParameterList = ProcessTypeSetupDAO.getSystemParameters( processTypeSetupForm.getProcessType() );
					for ( int i = 0; i < systemParameterList.size(); i++ )
					{
						sysParameter 		= (ProcessParameters)systemParameterList.get( i );
						parameterPresent 	= false;
						for( int j = 0; j < parameterList.size(); j++ )
						{
							parameter = (ProcessParameters)parameterList.get( j );
							if( sysParameter.getParamName().equalsIgnoreCase( parameter.getParamName() ) )
							{
								parameterPresent = true;
								if( !parameter.getSysParam() )
								{
									parameter.setSysParam( true );
								}
								break;
							}
						}

						if( !parameterPresent )
						{
							parameterList.add( sysParameter );
						}
					}
				}

				if( !showUserParameters && action.equalsIgnoreCase( "modify" ) )
				{
					processTypeSetupForm.getProcessParameters().add( new ProcessParameters() );
					session.setAttribute( "processList", getParentProcessNames() );
					session.setAttribute( "units", ProcessTypeSetupDAO.getUnitsOfMesurment() );
					request.setAttribute( "showUserParameters", "true" );
				}
				else if( !showUserParameters && ( action.equalsIgnoreCase( "view" ) || action.equalsIgnoreCase( "delete" ) ) )
				{
					request.setAttribute( "showUserParameters", "false" );
				}
				else if ( showUserParameters )
				{
                    session.setAttribute( "units", ProcessTypeSetupDAO.getUnitsOfMesurment() );
					request.setAttribute( "showUserParameters", "true" );
				}
				ProcessTypeSetupDAO.setIsEditable( processTypeSetupForm ); //added by sujan on 30th dec 2004.

                HashMap comboMap = ProcessTypeSetupDAO.getComboMapForProcessType( null, processTypeSetupForm.getProcessType() );
                checkParameterValuesInComboMap ( processTypeSetupForm.getProcessParameters(), comboMap );
                request.setAttribute ( "comboMap",  comboMap );
                /*if ( processTypeSetupForm.getProcessType() != null && processTypeSetupForm.getProcessType().equalsIgnoreCase( ProcessTypes.assembly ))
                {
                    request.setAttribute( "packageTypeList", PurchaseOrderDAO.loadPackageTypeList() );
                }*/

				retVal = "success";
			}
			catch( ScalarException e  )
			{
				e.printStackTrace();
				errors.put( processTypeSetupForm.getProcessName(), "Could load the process" );
			}
		}
		else if( action.equalsIgnoreCase("update") )
		{
			try
			{
				ProcessTypeSetupDAO.updateProcessDetails( processTypeSetupForm );
				info.put( processTypeSetupForm.getProcessName(), "updated successfully");
				retVal = "search";
			}
			catch ( ScalarException e )
			{
				errors.put( processTypeSetupForm.getProcessName(), "Could not be Updated " );
				retVal = "search";
			}
		}
		else if( action.equalsIgnoreCase( "confirmDelete" ) )
		{
			boolean processUsed = false;
			try
			{
				processUsed = ProcessTypeSetupDAO.checkProcessUsed( processTypeSetupForm );

				if( !processUsed )
				{
					ProcessTypeSetupDAO.deleteProcessDetails( processTypeSetupForm );
					info.put( processTypeSetupForm.getProcessName(), "deleted successfully" );
					retVal = "search";
				}
				else
				{
					ArrayList parameterList = processTypeSetupForm.getProcessParameters();
					ProcessParameters parameter 	= null;
					boolean showUserParameters		= false;

					errors.put( "Process could not be Deleted as it is being used in the Product Setup", "" );
					request.setAttribute( "confirm" , "true" );
					processTypeSetupForm.setAction( "view" );
					request.setAttribute( "showSystemParameters", "true" );

					for( int i = 0; i < parameterList.size(); i++ )
					{
						parameter = (ProcessParameters)parameterList.get( i );
						if( parameter.getSysParam() == false )
						{
							showUserParameters = true;
							break;
						}
					}
					if( showUserParameters )
					{
						request.setAttribute( "showUserParameters", "true" );
					}
					else
					{
						request.setAttribute( "showUserParameters", "false" );
					}

					retVal = "success";
				}
			}
			catch ( ScalarException e )
			{
				errors.put( processTypeSetupForm.getProcessName(), "Could not be Deleted " );
				retVal = "search";
			}
		}
        else if ( action.equalsIgnoreCase("loadPackageType"))
        {
            request.setAttribute( "packageTypeList", PurchaseOrderDAO.loadPackTypeList() );
            retVal = "addNewPackageType";
        }
        else if ( "loadAddMore".equalsIgnoreCase( action ) )
        {
            String processType      = request.getParameter ( "processType" );
            String processParameter = request.getParameter ( "processParameter" );
            request.setAttribute ( "processParameterValues", ProcessTypeSetupDAO.getProcessParameterValues ( null, processType, processParameter ) );
            retVal = "loadAddMore";
        }
        /*else if ( action.equalsIgnoreCase("savePackageType"))
        {

            String[] packageType      = request.getParameterValues("packageType");

            if( packageType != null )
            {
                int packageTypeSize = 0;
                try
                {
                    packageTypeSize =  packageType.length;
                }
                catch (Exception ex)
                {
                    packageTypeSize = 0;
                }
                ArrayList packageTypeList = new ArrayList(packageTypeSize);

                for(int count = 0; count < packageTypeSize; count++ )
                {
                   if( ( packageType[ count ] != null ) && ( !( "".equalsIgnoreCase( packageType[ count ].trim() ) ) ) )
                   {
                       packageTypeList.add( packageType[ count ] );
                   }
                }

                PurchaseOrderDAO.savePakageType( null,  packageTypeList );
                info.put ( INFO_PACKAGE_TYPE_SAVED_SUCCEFULLY, null );
                Logger.info( INFO_PACKAGE_TYPE_SAVED_SUCCEFULLY );
            }

            request.setAttribute( "packageTypeList", PurchaseOrderDAO.loadPackTypeList() );
            retVal = "success";
        }*/
        else if ( "saveProcessParameterValues".equalsIgnoreCase( action ) )
        {
            String[] parameterValues      = request.getParameterValues("processParameterVal");

            if( parameterValues != null )
            {
                int parameterValuesSize = 0;
                try
                {
                    parameterValuesSize =  parameterValues.length;
                }
                catch (Exception ex)
                {
                    parameterValuesSize = 0;
                }
                ArrayList parameterValuesList = new ArrayList(parameterValuesSize);

                for(int count = 0; count < parameterValuesSize; count++ )
                {
                   if( ( parameterValues[ count ] != null ) && ( !( "".equalsIgnoreCase( parameterValues[ count ].trim() ) ) ) )
                   {
                       parameterValuesList.add( parameterValues[ count ].trim() );
                   }
                }

                String processType      = request.getParameter ( "processType" );
                String processParameter = request.getParameter ( "processParameter" );
                ProcessTypeSetupDAO.saveProcessParameterValues ( null, processType, processParameter, parameterValuesList );
                info.put ( processParameter + "Saved Successfully", null );
                Logger.info( processParameter + "Saved Successfully" );
            }

            HashMap comboMap = ProcessTypeSetupDAO.getComboMapForProcessType( null, processTypeSetupForm.getProcessType() );
            checkParameterValuesInComboMap ( processTypeSetupForm.getProcessParameters(), comboMap );
            request.setAttribute ( "comboMap",  comboMap );
            retVal = "success";
        }
        else if ( action.equalsIgnoreCase("refresh"))
        {
            if( ( processList == null ) || ( units == null ) )
            {
                session.setAttribute( "processList", getParentProcessNames() );
                session.setAttribute( "units", ProcessTypeSetupDAO.getUnitsOfMesurment() );
            }
            request.setAttribute( "showSystemParameters", "true" );
            request.setAttribute( "showUserParameters", "true" );
            HashMap comboMap = ProcessTypeSetupDAO.getComboMapForProcessType( null, processTypeSetupForm.getProcessType() );
            checkParameterValuesInComboMap ( processTypeSetupForm.getProcessParameters(), comboMap );
            request.setAttribute ( "comboMap",  comboMap );
            /*if ( processTypeSetupForm.getProcessType() != null && processTypeSetupForm.getProcessType().equalsIgnoreCase( ProcessTypes.assembly ))
            {
                request.setAttribute( "packageTypeList", PurchaseOrderDAO.loadPackageTypeList() );
            }*/

            retVal = "success";
        }

		request.setAttribute( SessionKeys.ERROR_MESSAGES, errors );
		request.setAttribute( SessionKeys.INFO_MESSAGES, info );
		return ( mapping.findForward( retVal ) );
	}

	/**
	 * @param processTypeSetupForm
	 * @return
	 */
	private ArrayList fetchSystemParameters( ProcessTypeSetupForm processTypeSetupForm )
	{
		ArrayList parameters = new ArrayList();
		String processType 	 = processTypeSetupForm.getProcessType() ;
		
		if( processType != null && processType.length() > 0 )
		{
			try
			{
				parameters = ProcessTypeSetupDAO.getSystemParameters( processType );
			}
			catch(Exception e)
			{
				e.printStackTrace();
			}
		}
		return parameters;
	}

	public ArrayList<LabelValueBean> getParentProcessNames()
	{
		ArrayList<LabelValueBean> processList = new ArrayList<LabelValueBean>(0);
		
		processList.add( new LabelValueBean( "FAB", "FAB" ) );
		processList.add( new LabelValueBean( "Wafer Store", "Wafer Store" ) );
		processList.add( new LabelValueBean( "SORT", "SORT" ) );
		processList.add( new LabelValueBean( "Bumping", "Bumping" ) );
		processList.add( new LabelValueBean( "Die Bank", "Die Bank" ) );
		processList.add( new LabelValueBean( "Assembly", "Assembly" ) );
		processList.add( new LabelValueBean( "TEST", "TEST" ) );
		processList.add( new LabelValueBean( "Class Store", "Class Store" ) );
		processList.add( new LabelValueBean( "Mark & Pack", "Mark & Pack" ) );
		processList.add( new LabelValueBean( "Finished Goods", "Finished Goods" ) );
		
		return processList;
	}

    /**
     * used to add the process parameter value to combo if not exists.
     * @param processParametersList
     * @param comboMap
     */
    private void checkParameterValuesInComboMap ( ArrayList processParametersList, HashMap comboMap )
    {
        if ( processParametersList == null || comboMap == null )
        {
            return;
        }
        ProcessParameters processParameter  = null;
        ArrayList parameterValues           = null;
        LabelValueBean labelValueBean       = null;
        LabelValueBean parameterValue       = null;
        ArrayList unitsOfmeasurement= null;
        int unitsOfmeasurementSize  = 0;
        try
        {
            unitsOfmeasurement = ProcessTypeSetupDAO.getUnitsOfMesurment();
            unitsOfmeasurementSize = (unitsOfmeasurement == null ) ? 0 : unitsOfmeasurement.size();
        }
        catch ( Exception e )
        {
        }
        int processParametersSize = processParametersList.size();
        for ( int i=0; i < processParametersSize; i++ )
        {
            processParameter    = ( ProcessParameters ) processParametersList.get ( i );
            parameterValues     =   ( ArrayList )comboMap.get ( processParameter.getParamName() );
            if ( parameterValues != null && processParameter != null )
            {
                if ( processParameter.getParamVal() != null && processParameter.getParamVal().trim().length() != 0 )
                {
                    String paramUnit    = processParameter.getParamUnit();
                    String baseUOM      = null;
                    for ( int k = 0; k < unitsOfmeasurementSize; k++ )
                    {
                        UOM uom = ( UOM ) unitsOfmeasurement.get ( k );
                        if ( paramUnit != null && paramUnit.equalsIgnoreCase( uom.getUom() ) )
                        {
                            baseUOM = uom.getBaseUom();
                            break;
                        }
                    }
                    labelValueBean = new LabelValueBean ( processParameter.getParamVal(), processParameter.getParamVal() );
                    int parameterValuesSize = parameterValues.size();
                    boolean matchFound  = false;
                    String paramVal     = null;
                    for ( int j = 0; j < parameterValuesSize; j++ )
                    {
                        parameterValue  = ( LabelValueBean )parameterValues.get ( j );
                        paramVal        = labelValueBean.getValue();
                        if ( baseUOM != null )
                        {
                            if ( "DOUBLE".equalsIgnoreCase( baseUOM ) )
                            {
                                double tempParamVal         = 0;
                                double tempParameterValue   = 0;
                                try
                                {
                                    tempParamVal = Double.parseDouble ( paramVal.trim() );
                                    tempParameterValue = Double.parseDouble ( parameterValue.getValue() );
                                    if ( tempParamVal == tempParameterValue )
                                    {
                                        matchFound = true;
                                        break;
                                    }
                                }catch ( Exception e ) { }

                            }
                            else if ( "INT".equalsIgnoreCase( baseUOM ) )
                            {
                                int tempParamVal         = 0;
                                int tempParameterValue   = 0;
                                try
                                {
                                    tempParamVal = Integer.parseInt ( paramVal.trim() );
                                    tempParameterValue = Integer.parseInt ( parameterValue.getValue() );
                                    if ( tempParamVal == tempParameterValue )
                                    {
                                        matchFound = true;
                                        break;
                                    }
                                }catch ( Exception e ) { }
                            }
                            else if ( labelValueBean.getValue().equals( parameterValue.getValue() ) )
                            {
                                matchFound  = true;
                                break;
                            }
                        }
                        else if ( labelValueBean.getValue().equals( parameterValue.getValue() ) )
                        {
                            matchFound  = true;
                            break;
                        }
                    }
                    if ( !matchFound )
                    {
                        parameterValues.add ( labelValueBean );
                    }
                }
            }
        }
    }
}